// 线程不安全的懒汉模式
#include <chrono>
#include <iostream>
#include <string>
#include <thread>

class Singleton {
public:
    static Singleton* getInstance(
        const std::string& value) {  // 对外接口，通过这个获取单例
        if (instance == nullptr) {
            instance = new Singleton(value);
        }
        return instance;
    }

    std::string value() const { return value_; }

protected:
    std::string value_;
    static Singleton* instance;  // 单例为静态成员变量，类内声明，类外初始化

    void operator=(const Singleton&) =
        delete;  // 删除拷贝赋值运算符，类的用户不能对单例对象进行拷贝赋值操作

    Singleton(Singleton& other) = delete;  // 删除拷贝构造函数
    Singleton(const std::string value)     // 构造函数设为私有
        : value_(value) {}
};

Singleton* Singleton::instance = nullptr;  // 类外初始化静态变量

void ThreadFoo() {
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Singleton* singleton = Singleton::getInstance("FOO");
    std::cout << "value: " << singleton->value() << "\n";
}

void ThreadBar() {
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    Singleton* singleton = Singleton::getInstance("BAR");
    std::cout << "value: " << singleton->value() << "\n";
}

int main() {
    std::cout << "假如重复运行多次会发现，有几率出现打印出的value不同的情况\n"
              << "足以见得这样是线程不安全的\n";
    /*
     * value: BAR
     * value: FOO
     */
    std::thread t1(ThreadFoo);
    std::thread t2(ThreadBar);
    t1.join();
    t2.join();

    return 0;
}